#include "TcpServer.h"
#include "Connection.h"

TcpServer::TcpServer(const std::string &ip, const uint16_t port,int threadnum)
    :threadnum_(threadnum),mainloop_(new EventLoop(true)),acceptor_(mainloop_.get(), ip, port),threadpool_(threadnum_,"IO")
{

    // mainloop_ = new EventLoop;
    // printf("main epollfd:%d\n",mainloop_->ep()->epollfd_);
    mainloop_->setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));

    //acceptor_ = new Acceptor(mainloop_.get(), ip, port);
    acceptor_.setnewconnectioncb(std::bind(&TcpServer::newconnection, this, std::placeholders::_1));

    // threadpool_ = new ThreadPool(threadnum_,"IO");

    // 创建三个IO线程
    for(int i = 0;i<threadnum_;i++)
    {
        // subloops_.push_back(/*new EventLoop*/std::make_unique<EventLoop>());
        subloops_.emplace_back(new EventLoop(false,20,80));
        // printf("subloops_[%d] epollfd:%d\n",i,subloops_[i]->ep()->epollfd_);
        subloops_[i]->setepolltimeoutcallback(std::bind(&TcpServer::epolltimeout, this, std::placeholders::_1));
        subloops_[i]->setremoveconncallback(std::bind(&TcpServer::removeconn,this,std::placeholders::_1));
        threadpool_.addtask(std::bind(&EventLoop::run,subloops_[i].get()));
    }    
}

TcpServer::~TcpServer()
{
    // delete acceptor_;
    // delete mainloop_;
    // for (auto &aa : conns_)
    // {
    //     delete aa.second;
    // }

    // for(auto &aa:subloops_)
    // {
    //     delete aa;
    // }
    // delete threadpool_;
}

void TcpServer::start()
{
    mainloop_->run();
}

void TcpServer::newconnection(std::unique_ptr<Socket> clientsock)
{   

    // 主线程中创建     IO线程中使用
    printf("clientsock->fd(): %d\n",clientsock->fd());
    int clientfd = clientsock->fd();
    //printf("++++++++++++++++++++++++++:::%d  %d  %d\n",clientsock->fd(),threadnum_,clientfd%threadnum_);                               
    std::shared_ptr<Connection> conn(new Connection(subloops_[clientfd%threadnum_].get(), std::move(clientsock)));// move了

    conn->setclosecallback(std::bind(&TcpServer::closeconnection, this, std::placeholders::_1));
    conn->seterrorcallback(std::bind(&TcpServer::errorconnection, this, std::placeholders::_1));

    conn->sethaddlemsgcallback(std::bind(&TcpServer::haddlemessage, this, std::placeholders::_1, std::placeholders::_2));

    conn->setsendcompletecallback(std::bind(&TcpServer::sendcomplete, this, std::placeholders::_1));

    

    //printf("New client connected: %s:%d\n", conn->ip().c_str(), conn->port());
    //conns_[conn->fd()] = conn;  // 把conn存放到Tcpserver的map容器中

    {
        std::lock_guard<std::mutex> gd(mmutex_);
        conns_[conn->fd()] = conn;  
    }

    subloops_[clientfd%threadnum_]->newconnection(conn);  // 把conn存放到Eventloop的map容器中

    if(newconnectioncb_) newconnectioncb_(conn);

   
}

void TcpServer::closeconnection(std::shared_ptr<Connection> conn)
{
    if(closeconnectioncb_) closeconnectioncb_(conn);
    //printf("client(eventfd=%d)disconnected\n", conn->fd());
    // close(conn->fd());
    {
        std::lock_guard<std::mutex> gd(mmutex_);
        conns_.erase(conn->fd());
    }
    
    // delete conn;
}
void TcpServer::errorconnection(std::shared_ptr<Connection> conn)
{
    if(errorconnectioncb_) errorconnectioncb_(conn);
    //printf("else error\n");
    // close(conn->fd());
    {
        std::lock_guard<std::mutex> gd(mmutex_);
        conns_.erase(conn->fd());
    }
    // delete conn;
}

// 处理数据的逻辑放到这里
void TcpServer::haddlemessage(std::shared_ptr<Connection> conn, std::string& message)
{
    if(onmessagecb_) onmessagecb_(conn,message);
    // message = "replay:" + message; // 回显业务
    // int len = message.size();

    // std::string tmpbuf((char *)&len, 4);
    // tmpbuf.append(message);

    // // write(conn->fd(), tmpbuf.data(), tmpbuf.size());
    // conn->send(tmpbuf.data(), tmpbuf.size());
}

void TcpServer::sendcomplete(std::shared_ptr<Connection> conn)
{
    //printf("send complete\n");
    if(sendcompletecb_) sendcompletecb_(conn);
}

void TcpServer::epolltimeout(EventLoop *loop)
{
    //printf("epoll_wait() timeout\n");

    timeoutcb_(loop);
}

// 设置新连接建立时的回调（参数：Connection指针）
void TcpServer::setNewConnectionCB(std::function<void(std::shared_ptr<Connection>)> fn)
{
    newconnectioncb_ = fn;
}

// 设置连接关闭时的回调（参数：Connection指针）
void TcpServer::setCloseConnectionCB(std::function<void(std::shared_ptr<Connection>)> fn)
{
    closeconnectioncb_ = fn;
}

// 设置连接错误时的回调（参数：Connection指针）
void TcpServer::setErrorConnectionCB(std::function<void(std::shared_ptr<Connection>)> fn)
{
    errorconnectioncb_ = fn;
}

// 设置消息到达时的回调（参数：Connection指针 + 消息内容引用）
void TcpServer::setOnMessageCB(std::function<void(std::shared_ptr<Connection>, std::string &message)> fn)
{
    onmessagecb_ = fn;
}

// 设置数据发送完成时的回调（参数：Connection指针）
void TcpServer::setSendCompleteCB(std::function<void(std::shared_ptr<Connection>)> fn)
{
    sendcompletecb_ = fn;
}

// 设置超时事件回调（参数：EventLoop指针）
void TcpServer::setTimeoutCB(std::function<void(EventLoop *)> fn)
{
    timeoutcb_ = fn;
}

void TcpServer::removeconn(int fd)
{
    std::lock_guard<std::mutex> gd(mmutex_);
    conns_.erase(fd);  
   
}

void TcpServer::stop()
{
    mainloop_->stop();
    printf("主事件循环已经停止\n");

    for(auto &aa: subloops_){
        aa->stop();
    }
    printf("从事件循环已经停止\n");

    threadpool_.stop();
    printf("IO线程停止\n");
}